﻿using log4net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Windows.Forms;

namespace HobSoft.SoccerBet2014.Server.SiteManagerSchedule
{
    using Domain.Common.Site;
    using Domain.Configuration;
    using Domain.DataService;
    using Domain.Factory;
    using Domain.Models;
    using Domain.Schedule;
    public class ScheduleManager
    {
        protected ScheduleSettingConfiguration Setting;
        protected readonly IBetSiteManagerFactory managerFactory;
        protected readonly IScheduleTimerFactory timerFactory;
        protected readonly ILog infoLoger = LogManager.GetLogger("ApplicationCacheLog");
        protected BindingList<SiteManagerView> AccountSiteManagerCollection;
        protected DataGridView bindDataGrid;
        protected IList<Bookmaker> bookers;
        public ScheduleManager(IBetSiteManagerFactory fact,IScheduleTimerFactory timerFact)
        {
            managerFactory = fact;
            timerFactory = timerFact;
            AccountSiteManagerCollection = new BindingList<SiteManagerView>();
            Setting = (ScheduleSettingConfiguration)ConfigurationManager.GetSection("bookmaker.schedule");
        }

        public virtual void BindToGridControl(DataGridView grid)
        {
            bindDataGrid = grid;
            grid.DataSource = AccountSiteManagerCollection;
        }

        public virtual void Initialize(IList<Bookmaker> bookmakers)
        {
            bookers = bookmakers;
            AccountSiteManagerCollection.Clear();
            foreach (var bm in bookmakers)
            {
                var bmConfig = Setting.SiteBmConfiguration.FirstOrDefault(s => s.BmID == bm.BmID);
                if (bmConfig == null) continue;
                foreach (var account in bm.Accounts)
                {
                    if (!account.Available) continue;
                    if (!AccountSiteManagerCollection.Any(a => a.BmID == account.BmID && a.Account.Equals(account.Account, System.StringComparison.OrdinalIgnoreCase)))
                    {
                        var manager = managerFactory.CreateOrGet(account.BmID, account.Account, bm.DefaultHost);
                        var siteSessionManager =  manager as SessionManagerBase;
                        var accountManagerView = new SiteManagerView(account.BmID, account.Account, account.Password, siteSessionManager);
                        if (!manager.IsInitialize)
                            manager.Initialize(bm.DefaultHost, account.BmID, account.Account);
                        siteSessionManager.OnScheduleRequestBefore += Manager_OnScheduleRequestBefore;
                        siteSessionManager.OnScheduleRequestOver += Manager_OnScheduleRequestOver;
                        siteSessionManager.OnScheduleError += Manager_OnScheduleError;
                        AccountSiteManagerCollection.Add(accountManagerView);
                    }
                }
            }
        }

        private void Manager_OnScheduleError(IBetSiteManagerService sender, BetSiteRequestType type, string message)
        {
            //throw new System.NotImplementedException();
        }

        private void Manager_OnScheduleRequestOver(IBetSiteManagerService sender, BetSiteRequestType type, byte bmId, string account)
        {
            var typeDesc = CaseTypeDescription(type);
            var bm = bookers.FirstOrDefault(b => b.BmID == bmId);
            infoLoger.InfoFormat("【{0}】{1}完成请求{2}", bm == null ? "" : bm.BmName, account, typeDesc);
        }

        private void Manager_OnScheduleRequestBefore(IBetSiteManagerService sender, BetSiteRequestType type, byte bmId, string account)
        {
            var typeDesc = CaseTypeDescription(type);
            var bm = bookers.FirstOrDefault(b => b.BmID == bmId);
            infoLoger.InfoFormat("【{0}】{1}开始请求{2}", bm == null ? "" : bm.BmName, account, typeDesc);
        }

        private string CaseTypeDescription(BetSiteRequestType type)
        {
            var result = string.Empty;
            switch (type)
            {
                case BetSiteRequestType.Live:
                    result = "滚球数据";
                    break;
                case BetSiteRequestType.Today:
                    result = "今日早盘数据";
                    break;
                case BetSiteRequestType.Early:
                    result = "早盘数据";
                    break;
                default:
                    break;
            }
            return result;
        }

        public virtual void Signup()
        {
            if (infoLoger != null)
                infoLoger.Info("开始发出所有账号登陆请求.");

            foreach (var item in AccountSiteManagerCollection)
            {
                item.Signup();
            }
        }

        public virtual void Start()
        {
            foreach (var item in AccountSiteManagerCollection)
            {
                var config = Setting.SiteBmConfiguration.FirstOrDefault(s => s.BmID == item.BmID);
                if (config != null)
                {
                    var timer = timerFactory.CreateOrGet();
                    item.Start(timer, config);
                }
            }
        }

        public virtual void Stop()
        {
            foreach (var item in AccountSiteManagerCollection)
            {
                item.Stop();
            }
        }
    }
}
